òɾۿûѧϰʹá
ԭַhttps://www.joinquant.com/post/11713

ԭһ˵ʽ鵽ԭĺ߽ۡ


ԭĲԴ£

import pandas as pd
import datetime
import numpy as np
import math
import time
import jqdata
from pandas import Series, DataFrame
import statsmodels.api as sm
import scipy.stats as scs
import matplotlib.pyplot as plt
#from pandas import Series, DataFrame

#زǰҪ
def initialize(context):
    set_params()        #1ò߲
    set_variables() #2м
    set_backtest()   #3ûز

#1
#ò߲
def set_params():
    g.tc=15  # Ƶ
    g.yb=63  # 
    g.N=20   # ֲĿ
    
    #ARL=total_liability/total_assetsARL=total_liability/total_assets
    #g.factors=["market_cap","roe","pe_ratio","eps"] # ѡĿ
    #g.factors=["market_cap","roe","pe_ratio","ps_ratio"] # ûѡ
    #g.factors=["circulating_market_cap","eps","net_profit_to_total_revenue","roe","pcf_ratio","ps_ratio","pe_ratio","turnover_ratio"] # ûѡ
    g.factors=["circulating_market_cap","ps_ratio","eps","net_profit_to_total_revenue","roe","pcf_ratio","pe_ratio","turnover_ratio"] # ûѡ
    # ӵȨ1ʾֵԽСԽã-1ʾֵԽԽ
    g.weights=[[-1],[1],[-1],[-1],[-1],[-1],[1],[1]]
#2
#м
def set_variables():
    g.t=0              #¼زе
    g.if_trade=False   #Ƿ

#3
#ûز
def set_backtest():
    set_option('use_real_price', True)#ʵ۸
    log.set_level('order', 'error')

'''
================================================================================
ÿ쿪ǰ
================================================================================
'''

#ÿ쿪ǰҪ
def before_trading_start(context):
    if g.t%g.tc==0:
        #ÿg.tc죬һ
        g.if_trade=True 
        # 
        set_slip_fee(context) 
        # ÿйƱأõǰ̵Ļ300Ʊز޳ǰ߼ڼͣƵĹƱ
        g.all_stocks = set_feasible_stocks(get_index_stocks('000300.XSHG'),g.yb,context)
        # ѯв
        #ʱᱨerror˵g.qлǰ
        #g.q = query(valuation,balance,cash_flow,income,indicator).filter(valuation.code.in_(g.all_stocks))
    g.t+=1

#4
# ÿйƱ
# ˵ͣƵĹƱ,ɸѡǰdaysδͣƹƱ
# 룺stock_listΪlist,daysΪintͣcontextAPI
# list
def set_feasible_stocks(stock_list,days,context):
    # õǷͣϢdataframeͣƵ1δͣƵ0
    suspened_info_df = get_price(list(stock_list), start_date=context.current_dt, end_date=context.current_dt, frequency='daily', fields='paused')['paused'].T
    # ͣƹƱ dataframe
    unsuspened_index = suspened_info_df.iloc[:,0]<1
    # õδͣƹƱĴlist:
    unsuspened_stocks = suspened_info_df[unsuspened_index].index
    # һɸѡǰdaysδͣƵĹƱlist:
    feasible_stocks=[]
    current_data=get_current_data()
    #ȡָǷͣƣΪ0ûͣ
    for stock in unsuspened_stocks:
        if sum(attribute_history(stock, days, unit='1d',fields=('paused'),skip_paused=False))[0]==0:
            feasible_stocks.append(stock)
    return feasible_stocks
    
#5
# ݲͬʱû
def set_slip_fee(context):
    # Ϊ0
    set_slippage(FixedSlippage(0)) 
    # ݲͬʱ
    dt=context.current_dt
    log.info(type(context.current_dt))
    
    if dt>datetime.datetime(2013,1, 1):
        set_commission(PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) 
        
    elif dt>datetime.datetime(2011,1, 1):
        set_commission(PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5))
            
    elif dt>datetime.datetime(2009,1, 1):
        set_commission(PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5))
                
    else:
        set_commission(PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5))

'''
================================================================================
ÿ콻ʱ
================================================================================
'''
def handle_data(context, data):
    if g.if_trade==True:
    # ڵʲԷʽǵȶȨط
        g.everyStock=context.portfolio.portfolio_value/g.N
        # 򣬷һdataframe,йƱ롢е÷ֵ֡
        df_caiwu=getRankedFactors(g.factors,g.all_stocks)
        toBuy=df_caiwu.index[0:g.N]
        # ڲҪֲֵĹƱȫ
        order_stock_sell(context,toBuy)
        # ڲҪֲֵĹƱ䵽ķݶ
        order_stock_buy(context,toBuy)
    g.if_trade=False    

#6
#źţִ
#룺context,toBuy-list
#none
def order_stock_sell(context,toBuy):
    # ڲҪֲֵĹƱȫ
        for i in context.portfolio.positions:
            if i not in toBuy:
                order_target_value(i, 0)

#7
#źţִ
#룺context,toBuy-list
#none
def order_stock_buy(context,toBuy):
    # ڲҪֲֵĹƱ䵽ķݶ
    for i in toBuy:
        if i not in context.portfolio.positions:
            order_target_value(i,g.everyStock)

#9
#ȡ
#룺f-ȫͨõĲѯ,Ʊб
#ݣϵĹƱĴ-dataframe
def getRankedFactors(f,all_stocks):
    # ùƱĻ
    q = query(valuation,balance,cash_flow,income,indicator).filter(valuation.code.in_(all_stocks))
    df = get_fundamentals(q)
    #ȡָӵdf
    df1= df[f]
    #Ʊֵб
    df1.index = df.code
    #ֵֵ
    df1=df1.rank(axis=0, method='average', ascending=True)
    #д
    points=np.dot(df1.values,g.weights)
    #ּdf
    df1['points']=pd.Series(list(points),index=df1.index)
    #
    df1=df1.sort('points',ascending=True)
    #һֵdf
    return df1

'''
================================================================================
ÿ̺
================================================================================
'''
# ÿ̺Ҫ飨вҪ
def after_trading_end(context):
    return
